package controller;

import java.util.ArrayList;

import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

import entity.User;

import server.ClientData;
import server.ClientState;
import server.IProtocolHandler;
import server.ServerThread;
import xml.Message;
/**
 * Controller for SignIn
 * Some functions are commented because I want to use them but I don't see them in the XSD file
 * @author Hanlin
 */
public class SignInController implements IProtocolHandler {

	@Override
	public Message process(ClientState state, Message request) {
		entity.System system = entity.System.getInstance();
		entity.DecisionLinesEvent event; 
		
		Node signInRequest = request.contents.getFirstChild();
		NamedNodeMap map = signInRequest.getAttributes();
		String eventId = map.getNamedItem("id").getNodeValue();
		
		Node userNode = signInRequest.getFirstChild();
		NamedNodeMap userMap = userNode.getAttributes();
		String userName = userMap.getNamedItem("name").getNodeValue();
		String password = userMap.getNamedItem("password").getNodeValue();
		
		event = system.getEvent(eventId);
		int numRounds = event.getNumRounds();
		String behavior = event.getTurnType();
		String type = event.getEventType();
		String question = event.getQuestion();
		int numChoices = event.getNumChoices();
		int position = event.getNumUser();

		User user = null;
		
		ArrayList<User> users = event.getUsers();
		
		
		for(int i=0;i<users.size();i++){
			if(users.get(i).getUserName().equals(userName)){
				if(users.get(i).getPassword().equals(password)){
					user = users.get(i);
				}else{
					// They got the password wrong
					String invalidResponse = Message.responseHeader(map.getNamedItem("id").getNodeValue(), "Incorrect password for user: "+users.get(i).getUserName());
					invalidResponse += "<signInResponse id='"+eventId+"' behavior='"+behavior+"' type='"+type+"' question='"+question
							+"' numChoices='"+numChoices+"' numRounds='"+numRounds+"' position='"+position+"'/>";
					invalidResponse += "</response>";
					System.out.println(invalidResponse);
					return new Message(invalidResponse);
				}
			}
		}
		
		// If we didn't find the user already in the user list, add them
		if(user == null){
			event.userCreate(userName, password);
			system.updateEvent(eventId, event);
		}
		
		
		NamedNodeMap requestMap = request.contents.getAttributes();
		String response = Message.responseHeader(requestMap.getNamedItem("id").getNodeValue());

		response += "<signInResponse id='"+eventId+"' behavior='"+behavior+"' type='"+type+"' question='"+question+"' numChoices='"+numChoices+
				"' numRounds='"+numRounds+"' position='"+position+"'>";
		for(int i=0;i<event.getLines().size();i++)
		{
			response += "<choice value='"+event.getLines().get(i).getNameOfChoice()+"' index='"+event.getLines().get(i).getPosition()+"' />";
		}
		for(int i=0;i<event.getUsers().size();i++)
		{
			response += "<user name='"+event.getUsers().get(i).getUserName()+"' password='"+event.getUsers().get(i).getPassword()+"'/>";
		}
		response += "</signInResponse></response>";
		//response += "<signInResponse id='"+eventId+"' behavior='"+behavior+"' type='"+type+"' question='"+
		//question+"' numChoices='"+numChoices+"' numRounds='"+numRounds+"' position='"+position+"' /></response>";
		
		
		// Sorry for modifying your class, I'm trying to figure out broadcast messages and this is the first class
		// that uses those. -- Frank
		
		
		// Establish that this client is connected to the specified event in the client state
		// Use ID to sent broadcast messages later
		ClientData cd = new ClientData(eventId, userName);
		state.setData(cd);
		
		// Broadcast joinResponse to everyone else
		String joinResponse = Message.responseHeader(requestMap.getNamedItem("id").getNodeValue());
		joinResponse += "<joinResponse id='"+eventId+"'>"
				+"<user name='"+userMap.getNamedItem("name").getNodeValue()+"' password='"+userMap.getNamedItem("password").getNodeValue()+"'/>"
				+"</joinResponse></response>";
		ServerThread.broadcastMessage(new Message(joinResponse), eventId, state.id());
		
		return new Message(response);
	}

}


/* Relevant schema
<xs:element name='signInRequest'> 
  <xs:complexType>
    <!-- participant signs in with the following user/password -->
    <xs:sequence>
      <xs:element ref='user' minOccurs='1' maxOccurs='1'/>
    </xs:sequence>

    <!-- meeting to signIn -->
    <xs:attribute name='id'         type='xs:string' use='required'/>
  </xs:complexType>
</xs:element>

<!-- in signinResponse, client is given their ordinal number (0-based) -->
<xs:element name='signInResponse'> 
 <xs:complexType>
    <!-- all choices that exist, one at a time, as (string,index) entries -->
    <xs:sequence>
      <xs:element ref='choice' minOccurs='0' maxOccurs='unbounded'/>
      <xs:element ref='user' minOccurs='0' maxOccurs='unbounded'/>
    </xs:sequence>

    <xs:attribute name='id'         type='xs:string' use='required'/>   
    <xs:attribute name='behavior'   type="behaviorType" use='required'/>
    <xs:attribute name='type'       type='eventType' use='required'/>
    <xs:attribute name='question'   type='xs:string' use='required'/>
    <xs:attribute name='numChoices' type='xs:int'    use='required'/>
    <xs:attribute name='numRounds'  type='xs:int'    use='required'/>
    <xs:attribute name='position'   type='xs:int'    use='required'/>
  </xs:complexType>
</xs:element>

// This gets sent to everyone else currently connected
<xs:element name='joinResponse'> 
 <xs:complexType>
    <!-- user that is joining given event -->
    <xs:sequence>
      <xs:element ref='user' minOccurs='1' maxOccurs='unbounded'/>
    </xs:sequence>

    <xs:attribute name='id'         type='xs:string' use='required'/> 
 </xs:complexType>
 </xs:element>
*/